package com.lottery.game.websocket;

import com.alibaba.fastjson.JSONObject;
import com.lottery.game.common.constants.GameConstants;
import com.lottery.game.common.utils.DateUtils;
import com.lottery.game.core.modules.entity.user.ChatRecord;
import com.lottery.game.core.modules.entity.user.GameUser;
import com.lottery.game.core.modules.entity.user.RealNumber;
import com.lottery.game.core.modules.service.app.ChatRecordService;
import com.lottery.game.core.modules.service.app.GameUserService;
import com.lottery.game.core.modules.service.app.OperationalSetService;
import com.lottery.game.core.modules.service.redis.RedisService;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;

import java.io.IOException;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;

import lombok.extern.slf4j.Slf4j;

import static com.lottery.game.common.constants.GameConstants.CHAT_TYPE;

@Slf4j
public class CoreWebSocketHandler extends TextWebSocketHandler implements Serializable {

	private static final long serialVersionUID = -7735345628956384109L;

	public static Map<String, Map<String, WebSocketSession>> webSocketMap = new ConcurrentHashMap<String, Map<String, WebSocketSession>>();

	@Autowired
	private ChatRecordService chatRecordService;

	@Autowired
	private GameUserService gameUserService;

	@Autowired
	private OperationalSetService operationalSetService;

	@Autowired
	private RedisService redisFeignClient;

	/**
	 * 发消息处理
	 */
	@Override
	public void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
		log.info("---handleTextMessage---");

		String chartId = (String) session.getAttributes().get("chartId");
		// 后台管理系统 WS心跳处理
		if (GameConstants.WEBSOCKET_SYSTEM_HEART.equals(message.getPayload())) {
			JSONObject object = new JSONObject();
			// 如果后台管理系统发送了心跳请求，后台回复一条约定好的心跳回执
			object.put("msg", GameConstants.WEBSOCKET_SERVER_HEART);
			session.sendMessage(new TextMessage(object.toJSONString()));
			return;
		}

		// 消息类型
		String chatType = (String) session.getAttributes().get(CHAT_TYPE);
		String userId = (String) session.getAttributes().get("userId");

		// 构建消息数据
		ChatRecord chatRecord = new ChatRecord();
		UUID uuid = UUID.randomUUID();
		chatRecord.setId(uuid.toString());
		chatRecord.setChatType(chatType);
		chatRecord.setSenderUserid(userId);
		chatRecord.setMsgContent(message.getPayload());
		chatRecord.setMessageStatus("0");
		chatRecord.setTimestamp(DateUtils.getNowDateString());

		// 用户禁言状态，默认否
		boolean userBanned = false;
		// 房间群聊
		if (GameConstants.CHATTYPE_GROUPCHAT.equals(chatType)) {
			chatRecord.setRoomnumber(chartId);
			GameUser user = gameUserService.get(userId);
			if (user != null) {
				chatRecord.setSenderPhone(user.getPhone());
				chatRecord.setSendernickname(user.getUsername());
				chatRecord.setSenderphoto(user.getPhotourl());

			} else {
				chatRecord.setSenderPhone("null");
				chatRecord.setSendernickname(userId);
			}

			// 客服聊天
//		} else if (GameConstants.CHATTYPE_CUSSERVICECHAT.equals(chatType)) {
//			GameUser user = gameUserService.get(userId);
//			chatRecord.setSenderUserid(userId);
//			if (user != null) {
//				// 判断用户的禁言状态
//				chatRecord.setSenderPhone(user.getPhone());
//				chatRecord.setSendernickname(user.getUsername());
//				chatRecord.setSenderphoto(user.getPhotourl());
//
//			} else {
//				chatRecord.setSenderPhone("null");
//				chatRecord.setSendernickname(userId);
//			}
//			// 用户前端发放消息给客服时,推送一条通知给后端服务器
//			log.info("-----herehere-----");
//			Map<String, String> map = new HashMap<>(16);
//			map.put("sendUserId", userId);
//			TextMessage cusserviceNoticeMsg = new TextMessage(JSONObject.toJSONString(map));
//			CoreWebSocketHandler.sendMessageToAllUser(GameConstants.SYS_MSG_CUSSERVICECHAT_NOTICE, cusserviceNoticeMsg);

			// 客服回复
		} else if (GameConstants.CHATTYPE_CUSREPLY.equals(chatType)) {
			// TODO 管理员账户获取
			chatRecord.setSenderPhone("null");
			chatRecord.setSendernickname(userId);
			chatRecord.setReceiverUserid(chartId);

			// 系统websocket连接，默认不允许用户推送消息到后台，防止插入数据库影响数据
		} else if (GameConstants.CHATTYPE_SYSTEM_MSG.equals(chatType)) {
			userBanned = true;
		}
		/*
		 * else if(GameConstants.CHAT_TYPE_ROOM_MSG.equals(chatType)){ String roomId =
		 * (String) session.getAttributes().get("roomId");
		 * chatRecord.setRoomnumber(roomId); }
		 */

		// 构建消息
		TextMessage sendMsg = new TextMessage(JSONObject.toJSONString(chatRecord));

		// 没有禁言的用户才数据插入以及推送操作
		if (!StringUtils.isEmpty(chartId) && !userBanned) {
			Map<String, WebSocketSession> sessionMap = webSocketMap.get(chartId);
			if (sessionMap != null) {
				Iterator<Entry<String, WebSocketSession>> it = sessionMap.entrySet().iterator();
				while (it.hasNext()) {
					Entry<String, WebSocketSession> tmpSession = it.next();
					if (!tmpSession.getKey().equals(userId)) {
						sendMessageToUser(tmpSession.getValue(), sendMsg);
						chatRecord.setMessageStatus("1");
					}
				}
				String orginMsg = "";
				try {
					JSONObject obj = JSONObject.parseObject(chatRecord.getMsgContent());
					orginMsg = obj.getString("message");
					chatRecord.setOrginMsg(orginMsg);
					Boolean isBetsSend = obj.getBoolean("betsSend");
					if (isBetsSend != null) {
						if (isBetsSend) {
							chatRecord.setGameroomId("betsSend");
						}
					}
				} catch (Exception e) {
					e.printStackTrace();
				}
				// 存入数据库
				chatRecordService.addChatRecord(chatRecord);
			}
		}
	}

	/**
	 * 成功连接
	 */
	@Override
	public void afterConnectionEstablished(WebSocketSession session) throws Exception {
		String chartId = (String) session.getAttributes().get("chartId");
		String userId = (String) session.getAttributes().get("userId");

		if (chartId.equals(GameConstants.SYS_OVERALL)) {
			Map<String, WebSocketSession> sessionMap = webSocketMap.get(chartId);
			if (sessionMap == null) {
				sessionMap = new HashMap<String, WebSocketSession>();
			}
			String randomUserId = (String) session.getAttributes().get("randomUserId");
			sessionMap.put(randomUserId, session);
			webSocketMap.put(chartId, sessionMap);
		} else {
			Map<String, WebSocketSession> sessionMap = webSocketMap.get(chartId);
			if (sessionMap == null) {
				sessionMap = new HashMap<String, WebSocketSession>();
			}
			sessionMap.put(userId, session);
			webSocketMap.put(chartId, sessionMap);
		}
		// 推送真实人数消息 和虚拟人数
		int number = webSocketMap.get(chartId).size();
		Map<String, Object> map = new HashMap<>();
		Map<String, WebSocketSession> sessionMap1 = CoreWebSocketHandler.webSocketMap.get(GameConstants.SYS_OVERALL);
		RealNumber realNumber = new RealNumber();
		realNumber.setRoomNumber(chartId);
		realNumber.setRoomPeople(number);
		realNumber.setStatus("add");
		// 查询是否有虚拟人数
		List<Map<String, Object>> list = null;
		int random = 0;
		if (!StringUtils.isEmpty(chartId) && !chartId.equals("sys_Overall")) {
			list = operationalSetService.queryVirtualNumberSetByNum(chartId);
			if (list != null && list.size() >= 1) {
				String randoms = this.redisFeignClient.get(chartId);
				if (!StringUtils.isEmpty(randoms)) {
					random = Integer.parseInt(randoms);
				}

			} else {
				this.redisFeignClient.delete(chartId);
			}
		}
		realNumber.setRandomNumber(random);
		map.put("roomRealNumber", realNumber);
		TextMessage message = new TextMessage(JSONObject.toJSONString(map));
		if (sessionMap1 != null) {
			Iterator<Entry<String, WebSocketSession>> it = sessionMap1.entrySet().iterator();
			while (it.hasNext()) {
				Entry<String, WebSocketSession> tmpSession = it.next();
				if (!StringUtils.isEmpty(tmpSession.getValue())) {
					sendMessageToUser(tmpSession.getValue(), message);
				}
			}
		}
	}

	/**
	 * 出现异常的时候
	 */
	@Override
	public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
		if (session.isOpen()) {
			session.close();
		}
		String chartId = (String) session.getAttributes().get("chartId");
		String userId = (String) session.getAttributes().get("userId");
		String randomUserId = (String) session.getAttributes().get("randomUserId");
		webSocketMap.get(chartId).remove(userId);
		webSocketMap.get(GameConstants.SYS_OVERALL).remove(randomUserId);
	}

	/**
	 * 退出聊天的时候
	 */
	@Override
	public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception {
		String chartId = (String) session.getAttributes().get("chartId");
		String userId = (String) session.getAttributes().get("userId");
		String randomUserId = (String) session.getAttributes().get("randomUserId");
		if (webSocketMap.get(chartId) != null) {
			webSocketMap.get(chartId).remove(userId);
		}

		// Map<String, WebSocketSession> sessionMap = webSocketMap.get(chartId);
		// 发送消息
		Map<String, WebSocketSession> sessionMap1 = CoreWebSocketHandler.webSocketMap.get(GameConstants.SYS_OVERALL);
		if (sessionMap1 != null) {
			sessionMap1.remove(randomUserId);
		}

		int number = webSocketMap.get(chartId).size();
		Map<String, Object> map = new HashMap<>();
		RealNumber realNumber = new RealNumber();
		realNumber.setRoomNumber(chartId);
		realNumber.setRoomPeople(number);
		map.put("roomRealNumber", realNumber);
		realNumber.setRoomPeople(number);
		realNumber.setStatus("reduce");
		// 查询是否有虚拟人数
		List<Map<String, Object>> list = null;
		int random = 0;
		if (!StringUtils.isEmpty(chartId) && !chartId.equals("sys_Overall")) {
			list = operationalSetService.queryVirtualNumberSetByNum(chartId);
			if (list != null && list.size() >= 1) {
				String randoms = this.redisFeignClient.get(chartId);
				if (!StringUtils.isEmpty(randoms)) {
					random = Integer.parseInt(randoms);
				}

			} else {
				this.redisFeignClient.delete(chartId);
			}
		}
		realNumber.setRandomNumber(random);
		map.put("roomRealNumber", realNumber);
		TextMessage message = new TextMessage(JSONObject.toJSONString(map));
		if (sessionMap1 != null) {
			Iterator<Entry<String, WebSocketSession>> it = sessionMap1.entrySet().iterator();
			while (it.hasNext()) {
				Entry<String, WebSocketSession> tmpSession = it.next();
				if (!StringUtils.isEmpty(tmpSession.getValue())) {
					sendMessageToUser(tmpSession.getValue(), message);
				}

			}
		}
	}

	/**
	 * 发消息（无论是否在线）
	 *
	 * @param session
	 * @param message
	 */
	public static void sendMessageToUser(WebSocketSession session, TextMessage message) {
		if (session != null) {
			synchronized (session) {
				try {
					session.sendMessage(message);
				} catch (IOException e) {
					log.error(e.getMessage(), e);
				}
			}
		}
	}

	/**
	 * 发消息给所有人
	 *
	 * @param chartId 消息类型
	 * @param message 消息文本
	 */
	public static void sendMessageToAllUser(String chartId, TextMessage message) {
		Map<String, WebSocketSession> sessionMap = webSocketMap.get(chartId);
		if (sessionMap != null) {
			Iterator<Entry<String, WebSocketSession>> it = sessionMap.entrySet().iterator();
			while (it.hasNext()) {
				Entry<String, WebSocketSession> tmpSession = it.next();
				sendMessageToUser(tmpSession.getValue(), message);
			}
		}
	}
}
